package com.eastfair.venuebooking.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eastfair.boot.service.SuperServiceImpl;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.venuebooking.dao.ContactRefMapper;
import com.eastfair.venuebooking.dto.*;
import com.eastfair.venuebooking.entity.ContactRef;
import com.eastfair.venuebooking.enums.VenueBookingMoudleEnum;
import com.eastfair.venuebooking.service.ContactRefService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 业务实现类
 * 联系人关联表
 * </p>
 *
 * @author clm
 * @date 2022-06-13
 */
@Slf4j
@Service
public class ContactRefServiceImpl extends SuperServiceImpl<ContactRefMapper, ContactRef> implements ContactRefService {


    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ContactRef> modelList) {
        modelList.forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ContactRef model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setTenantId(ContextUtil.getTenantId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    @Override
    public ContactRef getContactRef(ContactRefQuery query) {
        QueryWrapper<ContactRef> contactRefQueryWrapper = new QueryWrapper<>();
        contactRefQueryWrapper
                .lambda()
                .last("limit 1")
                .eq(query.getSubjectId() != null, ContactRef::getSubjectId, query.getSubjectId())
                .eq(StrUtil.isNotBlank(query.getSubjectType()), ContactRef::getSubjectType, query.getSubjectType())
                .eq(query.getContactId() != null, ContactRef::getContactId, query.getContactId())
                .eq(query.getImportant() != null, ContactRef::getImportant, query.getImportant());
        return getOne(contactRefQueryWrapper);
    }

    @Override
    public boolean existImportantContactRef(ContactRefQuery query) {
        log.info("existImportantContactRef - 主要联系人关系是否存在, query={}", query);
        QueryWrapper<ContactRef> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ContactRef::getIsDeleted, BusinessConstant.DELETE_NO)
                .in(query.getContactIdList() != null && !query.getContactIdList().isEmpty(),
                        ContactRef::getContactId, query.getContactIdList())
                .eq(StrUtil.isNotBlank(query.getSubjectType()), ContactRef::getSubjectType, query.getSubjectType())
                .eq(ContactRef::getImportant, true)
        ;
        return count(queryWrapper) > 0;
    }

    @Override
    public boolean existCustomerImportantContractRefByContactIds(List<Long> contactIds) {
        ContactRefQuery query = new ContactRefQuery();
        query.setContactIdList(contactIds);
        query.setSubjectType(VenueBookingMoudleEnum.CUSTOMER.getCode());
        return existImportantContactRef(query);
    }

    @Override
    public boolean existOpportunityImportantContractRefByContactIds(List<Long> contactIds) {
        ContactRefQuery query = new ContactRefQuery();
        query.setContactIdList(contactIds);
        query.setSubjectType(VenueBookingMoudleEnum.BUSINESS_OPPORTUNITY.getCode());
        return existImportantContactRef(query);
    }

    @Override
    public boolean updateContactRef(ContactRefDTO updateDTO) {
        UpdateWrapper<ContactRef> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda()
                .eq(updateDTO.getContactId() != null, ContactRef::getContactId, updateDTO.getContactId())
                .eq(updateDTO.getSubjectId() != null, ContactRef::getSubjectId, updateDTO.getSubjectId())
                .eq(updateDTO.getSubjectType() != null, ContactRef::getSubjectType, updateDTO.getSubjectType())
                .set(updateDTO.getImportant() != null, ContactRef::getImportant, updateDTO.getImportant())
        ;
        return update(updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateImportant(ContactRefDTO updateDTO) {
        // 先把首要联系人都置为非首要
        if (updateDTO.getImportant()) {
            updateUnimportant(updateDTO);
        }
        // 更新首要联系人
        return updateContactRef(updateDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUnimportant(ContactRefDTO updateDTO) {
        UpdateWrapper<ContactRef> contactRefUpdateWrapper = new UpdateWrapper<>();
        contactRefUpdateWrapper.lambda()
                .eq(updateDTO.getSubjectId() != null, ContactRef::getSubjectId, updateDTO.getSubjectId())
                .eq(StrUtil.isNotBlank(updateDTO.getSubjectType()), ContactRef::getSubjectType, updateDTO.getSubjectType())
                .eq(ContactRef::getImportant, true)
                .set(ContactRef::getImportant, false);
        return update(contactRefUpdateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateChooseContactRef(ContactRefDTO updateDTO) {
        ContactRefQuery contactRefPageQuery = new ContactRefQuery();
        contactRefPageQuery.setSubjectId(updateDTO.getSubjectId());
        contactRefPageQuery.setSubjectType(updateDTO.getSubjectType());
        contactRefPageQuery.setContactId(updateDTO.getContactId());
        ContactRef rawContactRef = getContactRef(contactRefPageQuery);

        if (rawContactRef != null) {
            // 客户关系已存在
            if (updateDTO.getImportant()) {
                // 更新首要联系人
                updateImportant(updateDTO);
            } else {
                // 更新次要联系人
                updateContactRef(updateDTO);
            }
        } else {
            // 客户关系不存在
            if (updateDTO.getImportant()) {
                // 更新其他联系人为次要联系人
                updateUnimportant(updateDTO);
            }
            // 保存联系人
            ContactRef contactRef = BeanUtil.toBean(updateDTO, ContactRef.class);
            save(contactRef);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeContactRef(ContactRefDTO updateDTO) {
        // 移除联系人关联
        QueryWrapper<ContactRef> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .lambda()
                .in(updateDTO.getSubjectIds() != null && !updateDTO.getSubjectIds().isEmpty(),
                        ContactRef::getSubjectId, updateDTO.getSubjectIds())
                .eq(updateDTO.getSubjectId() != null, ContactRef::getSubjectId, updateDTO.getSubjectId())
                .eq(StrUtil.isNotBlank(updateDTO.getSubjectType()),
                        ContactRef::getSubjectType, updateDTO.getSubjectType())
                .in(updateDTO.getContactIds() != null && !updateDTO.getContactIds().isEmpty(),
                        ContactRef::getContactId, updateDTO.getContactIds())
                .eq(updateDTO.getContactId() != null, ContactRef::getContactId, updateDTO.getContactId())
        ;
        return remove(queryWrapper);
    }

    @Override
    public boolean removeByContactId(Long contactId) {
        ContactRefDTO updateDTO = new ContactRefDTO();
        updateDTO.setContactId(contactId);
        return removeContactRef(updateDTO);
    }
}
